package com.qfx.common.util;

/**
 * <h5>描述:自定义加密解密工具类</h5>
 * 
 * @author zhangpj	2018年11月22日 
 */
public class ToolCrypt {
	
	// 前缀混乱字符串长度
	private static final int PREFIX_CHAOS_LENGTH = 6;
	// 后缀混乱字符串长度
	private static final int SUFFIX_CHAOS_LENGTH = 7;
	
	/**
	 * <h5>功能:自定义加密</h5>
	 * 前缀干扰串+后缀长度+指定长度前缀+(加密前字符串单个字符+随机X位大小写字母和数字)+指定长度后缀+前缀长度+后缀干扰串
	 * 
	 * @author zhangpj	@date 2018年11月22日
	 * @param str 明文字符串
	 * @return 加密后字符串
	 */
	public static String encrypt(String str) {
		// 1.随机生成前后缀的长度
		int prefixLenth = ToolGenerateData.getIntData(10);
		int suffixLength = ToolGenerateData.getIntData(10);
		
		// 2.生成指定长度的前缀字符串(如果长度是0,则默认为7位)
		String prefix = ToolGenerateData.getStringRandomExt2(prefixLenth == 0 ? 7 :prefixLenth);
		
		// 3.获取前缀字符串中的第一个数字,设定为加密间隔字符串长度
		int spacingLength = ToolGenerateData.getFirstInt(prefix);
		if (spacingLength < 1) {
			spacingLength = 3;
		}
		
		// 4.生成指定长度的后缀字符串,如果间隔字符串长度<=后缀字符串长度,则后缀字符串为""
		String suffix = "";
		if (spacingLength < suffixLength) {
			suffix = ToolGenerateData.getStringRandomExt(suffixLength - spacingLength);
		}
		
		// 5.明文反转
		StringBuilder sbd = new StringBuilder(str).reverse();
		str = sbd.toString();
		char[] c = str.toCharArray();
		
		// 6.随机生成前缀混乱字符串(7位)和后缀混乱字符串(6位)
		String prefixChaosStr = ToolGenerateData.getStringRandomExt2(PREFIX_CHAOS_LENGTH);
		String suffixChaosStr = ToolGenerateData.getStringRandomExt2(SUFFIX_CHAOS_LENGTH);
		
		
		// 7.明文加密
		sbd.setLength(0);	// 清空sbd的内容,准备接收新内容
		sbd.append(prefixChaosStr);	// 添加前缀混乱字符串
		sbd.append(suffixLength);	// 添加后缀长度
		sbd.append(prefix);			// 添加前缀
		for (int i = 0; i < c.length; i++) {
			sbd.append(c[i]);		// 添加反转后的明文字符
			sbd.append(ToolGenerateData.getStringRandomExt(spacingLength));	// 添加间隔字符串
		}
		sbd.append(suffix);		// 添加后缀
		sbd.append(prefixLenth);// 添加前缀长度
		sbd.append(suffixChaosStr);// 添加后缀混乱字符春啊
		
		return sbd.toString();
	}
	
	/**
	 * <h5>功能:解密自定义加密后的数据</h5>
	 * 
	 * @author zhangpj	@date 2018年11月22日
	 * @param str 加密后字符串
	 * @param prefixLenth 加密后字符串前缀长度
	 * @param spacingLength 加密字符间隔长度
	 * @param suffixLength 加密后字符串后缀长度
	 * @return 解密后字符串
	 */
	public static String decrypt(String str){
		// 1.去除加密字符串的前后缀混乱字符串
		str = str.substring(PREFIX_CHAOS_LENGTH, str.length() - SUFFIX_CHAOS_LENGTH);
		
		// 2.获取前缀和后缀的长度
		int prefixLenth = Integer.parseInt(str.substring(str.length() - 1, str.length()));
		int suffixLength = Integer.parseInt(str.substring(0, 1));
		
		// 如果指定的前缀长度是0,则默认为7位
		if (prefixLenth == 0) {
			prefixLenth = 7;
		}
		
		// 3.获取前缀字符串内容
		String prefix = str.substring(1, prefixLenth + 1);
		
		// 4.获取间隔字符串长度
		int spacingLength = ToolGenerateData.getFirstInt(prefix);
		if (spacingLength < 1) {
			spacingLength = 3;
		}
		
		// 5.去掉前缀和后缀并转换成字符数组
		str = str.substring(prefixLenth + 1, str.length() - (suffixLength +1));
		char[] c = str.toCharArray();
		
		// 6.提取明文
		StringBuilder sbd = new StringBuilder();
		for (int i = 0; i < c.length; i++) {
			sbd.append(c[i]);
			i += spacingLength;
		}
		
		// 7.反转明文并输出
		return sbd.reverse().toString();
	}
	
	public static void main(String[] args) {
		for (int i = 0; i < 10; i++) {
			String pwd = encrypt("shuhunfazhang");
			System.out.println(pwd);
			String ss = decrypt(pwd);
			System.out.println(ss);
		}
	}
}
